---
title: "Arrays and Strings"
description: "Learn C arrays and strings from a JavaScript perspective. Understand array declaration, pointer relationships, multidimensional arrays, and string handling functions."
---

# Arrays and Strings

## 1. Introduction

### From JavaScript Arrays to C Arrays

In JavaScript, arrays are dynamic, flexible data structures that can hold mixed types and automatically resize. In C, arrays are fixed-size, contiguous memory blocks that require explicit management but offer superior performance and memory efficiency.

C arrays are fundamental building blocks that form the basis for more complex data structures. Understanding them is crucial for:
- Efficient memory usage
- Performance optimization
- Building custom data structures
- System programming

> 💡 **Key Concept**: C arrays are just contiguous blocks of memory. The array name is actually a pointer to the first element, making arrays and pointers closely related in C.

## 2. Array Basics

### 2.1 Array Declaration and Initialization

<UniversalEditor title="Array Declaration" compare={true}>
```javascript !! js
// JavaScript - dynamic arrays
let numbers = [1, 2, 3, 4, 5];
let mixed = [1, "hello", true, { name: "John" }];

// Arrays can grow and shrink
numbers.push(6);
numbers.pop();

// Array length is dynamic
console.log("Length:", numbers.length);

// Accessing elements
console.log("First element:", numbers[0]);
console.log("Last element:", numbers[numbers.length - 1]);

// Iterating
for (let i = 0; i < numbers.length; i++) {
    console.log(numbers[i]);
}

// Modern iteration
numbers.forEach(num => console.log(num));
```

```c !! c
#include <stdio.h>

int main() {
    // Array declaration - fixed size
    int numbers[5] = {1, 2, 3, 4, 5};
    
    // Array size must be known at compile time
    // int dynamic_array[];  // Error: size required
    
    // Alternative initialization
    int arr1[5] = {1, 2, 3};  // Rest filled with 0
    int arr2[] = {1, 2, 3, 4, 5};  // Size inferred
    
    // Array length is fixed
    int size = sizeof(numbers) / sizeof(numbers[0]);
    printf("Array size: %d\n", size);
    
    // Accessing elements
    printf("First element: %d\n", numbers[0]);
    printf("Last element: %d\n", numbers[4]);
    
    // Iterating
    for (int i = 0; i < 5; i++) {
        printf("numbers[%d] = %d\n", i, numbers[i]);
    }
    
    // Using sizeof for iteration
    for (int i = 0; i < sizeof(numbers) / sizeof(numbers[0]); i++) {
        printf("Element %d: %d\n", i, numbers[i]);
    }
    
    return 0;
}
```
</UniversalEditor>

### 2.2 Arrays and Pointers Relationship

<UniversalEditor title="Arrays and Pointers" compare={true}>
```javascript !! js
// JavaScript - arrays are objects
let arr = [1, 2, 3, 4, 5];

// Arrays have methods and properties
console.log("Length:", arr.length);
console.log("Type:", typeof arr);
console.log("Is Array:", Array.isArray(arr));

// Arrays are passed by reference
let ref = arr;
ref[0] = 100;
console.log("Original array:", arr[0]);  // 100

// Array methods
let doubled = arr.map(x => x * 2);
let sum = arr.reduce((a, b) => a + b, 0);
console.log("Doubled:", doubled);
console.log("Sum:", sum);
```

```c !! c
#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    
    // Array name is a pointer to first element
    int* ptr = arr;  // Same as: int* ptr = &arr[0];
    
    printf("Array name (ptr): %p\n", arr);
    printf("Pointer to first element: %p\n", &arr[0]);
    printf("Pointer value: %p\n", ptr);
    
    // Array indexing vs pointer arithmetic
    printf("arr[2] = %d\n", arr[2]);
    printf("*(ptr + 2) = %d\n", *(ptr + 2));
    printf("ptr[2] = %d\n", ptr[2]);  // Pointer can use array syntax
    
    // Modifying through pointer
    ptr[1] = 100;
    printf("After modification: arr[1] = %d\n", arr[1]);
    
    // Pointer arithmetic
    for (int* p = arr; p < arr + 5; p++) {
        printf("Value at %p: %d\n", p, *p);
    }
    
    // Array size vs pointer size
    printf("Array size: %zu bytes\n", sizeof(arr));
    printf("Pointer size: %zu bytes\n", sizeof(ptr));
    
    return 0;
}
```
</UniversalEditor>

### 2.3 Array Bounds and Safety

<UniversalEditor title="Array Bounds Safety" compare={true}>
```javascript !! js
// JavaScript - bounds checking
let arr = [1, 2, 3, 4, 5];

// Safe access
console.log("Valid access:", arr[2]);  // 3
console.log("Out of bounds:", arr[10]);  // undefined

// Array methods are safe
arr.push(6);  // Safe addition
arr.splice(1, 1);  // Safe removal

// Length property prevents out-of-bounds
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);  // Safe iteration
}

// Modern iteration methods
arr.forEach((item, index) => {
    console.log(`Index ${index}: ${item}`);
});
```

```c !! c
#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    
    // C does NOT check array bounds!
    printf("Valid access: arr[2] = %d\n", arr[2]);
    
    // DANGEROUS: Out of bounds access
    // This may crash or corrupt memory
    printf("Out of bounds: arr[10] = %d\n", arr[10]);  // Undefined behavior!
    
    // Safe iteration using bounds checking
    int size = sizeof(arr) / sizeof(arr[0]);
    for (int i = 0; i < size; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }
    
    // Pointer arithmetic with bounds checking
    int* ptr = arr;
    for (int i = 0; i < size; i++) {
        if (ptr + i < arr + size) {  // Bounds check
            printf("*(ptr + %d) = %d\n", i, *(ptr + i));
        }
    }
    
    // Common mistake: off-by-one error
    // for (int i = 0; i <= size; i++)  // WRONG! Goes out of bounds
    
    return 0;
}
```
</UniversalEditor>

## 3. Multidimensional Arrays

### 3.1 2D Arrays

<UniversalEditor title="2D Arrays" compare={true}>
```javascript !! js
// JavaScript - nested arrays
let matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];

// Accessing elements
console.log("Element [1][2]:", matrix[1][2]);  // 6

// Iterating through 2D array
for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
        console.log(`matrix[${i}][${j}] = ${matrix[i][j]}`);
    }
}

// Modern iteration
matrix.forEach((row, i) => {
    row.forEach((element, j) => {
        console.log(`matrix[${i}][${j}] = ${element}`);
    });
});

// Dynamic sizing
matrix.push([10, 11, 12]);
matrix[0].push(4);
```

```c !! c
#include <stdio.h>

int main() {
    // 2D array declaration
    int matrix[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };
    
    // Accessing elements
    printf("Element [1][2]: %d\n", matrix[1][2]);  // 6
    
    // Iterating through 2D array
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j]);
        }
    }
    
    // Array of pointers approach (more flexible)
    int* rows[3];
    int row1[] = {1, 2, 3};
    int row2[] = {4, 5, 6};
    int row3[] = {7, 8, 9};
    
    rows[0] = row1;
    rows[1] = row2;
    rows[2] = row3;
    
    // Accessing through pointer array
    printf("Using pointer array: %d\n", rows[1][2]);  // 6
    
    // Memory layout visualization
    printf("Memory addresses:\n");
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("&matrix[%d][%d] = %p\n", i, j, &matrix[i][j]);
        }
    }
    
    return 0;
}
```
</UniversalEditor>

### 3.2 Higher Dimensional Arrays

<UniversalEditor title="Higher Dimensional Arrays" compare={true}>
```javascript !! js
// JavaScript - nested arrays for any dimension
let cube = [
    [
        [1, 2],
        [3, 4]
    ],
    [
        [5, 6],
        [7, 8]
    ]
];

// Accessing 3D array
console.log("cube[1][0][1]:", cube[1][0][1]);  // 6

// Iterating through 3D array
for (let i = 0; i < cube.length; i++) {
    for (let j = 0; j < cube[i].length; j++) {
        for (let k = 0; k < cube[i][j].length; k++) {
            console.log(`cube[${i}][${j}][${k}] = ${cube[i][j][k]}`);
        }
    }
}

// Dynamic dimensions
cube.push([[9, 10], [11, 12]]);
```

```c !! c
#include <stdio.h>

int main() {
    // 3D array declaration
    int cube[2][2][2] = {
        {
            {1, 2},
            {3, 4}
        },
        {
            {5, 6},
            {7, 8}
        }
    };
    
    // Accessing 3D array
    printf("cube[1][0][1]: %d\n", cube[1][0][1]);  // 6
    
    // Iterating through 3D array
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                printf("cube[%d][%d][%d] = %d\n", i, j, k, cube[i][j][k]);
            }
        }
    }
    
    // Array size calculation
    int total_elements = sizeof(cube) / sizeof(cube[0][0][0]);
    printf("Total elements: %d\n", total_elements);
    
    // Memory layout (contiguous)
    printf("Memory layout:\n");
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                printf("&cube[%d][%d][%d] = %p\n", i, j, k, &cube[i][j][k]);
            }
        }
    }
    
    return 0;
}
```
</UniversalEditor>

## 4. String Handling

### 4.1 C Strings vs JavaScript Strings

<UniversalEditor title="String Comparison" compare={true}>
```javascript !! js
// JavaScript - strings are objects
let str = "Hello, World!";
let str2 = 'Single quotes work too';
let template = `Template literal: ${str}`;

// String properties and methods
console.log("Length:", str.length);
console.log("Uppercase:", str.toUpperCase());
console.log("Substring:", str.substring(0, 5));
console.log("Split:", str.split(", "));

// String concatenation
let result = str + " " + str2;
let result2 = `${str} ${str2}`;

// String comparison
console.log("Equal:", str === "Hello, World!");
console.log("Contains:", str.includes("World"));

// String iteration
for (let char of str) {
    console.log(char);
}

// String is immutable
let upper = str.toUpperCase();
console.log("Original:", str);
console.log("Modified:", upper);
```

```c !! c
#include <stdio.h>
#include <string.h>

int main() {
    // C strings are character arrays
    char str[] = "Hello, World!";
    char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};  // Null-terminated
    
    // String length (excluding null terminator)
    printf("Length: %zu\n", strlen(str));
    printf("Array size: %zu\n", sizeof(str));  // Includes null terminator
    
    // String functions
    char upper[20];
    strcpy(upper, str);
    for (int i = 0; upper[i] != '\0'; i++) {
        if (upper[i] >= 'a' && upper[i] <= 'z') {
            upper[i] = upper[i] - 32;  // Convert to uppercase
        }
    }
    printf("Uppercase: %s\n", upper);
    
    // String concatenation
    char result[50];
    strcpy(result, str);
    strcat(result, " ");
    strcat(result, "C Programming");
    printf("Concatenated: %s\n", result);
    
    // String comparison
    printf("Equal: %d\n", strcmp(str, "Hello, World!") == 0);
    printf("Contains 'World': %s\n", strstr(str, "World") ? "Yes" : "No");
    
    // String iteration
    for (int i = 0; str[i] != '\0'; i++) {
        printf("str[%d] = '%c'\n", i, str[i]);
    }
    
    // Null terminator importance
    printf("Null terminator: str[13] = %d\n", str[13]);
    
    return 0;
}
```
</UniversalEditor>

### 4.2 String Functions and Safety

<UniversalEditor title="String Functions" compare={true}>
```javascript !! js
// JavaScript - safe string operations
let text = "Hello, World!";

// Safe substring operations
console.log("Substring:", text.substring(0, 5));  // "Hello"
console.log("Slice:", text.slice(-6));  // "World!"

// Safe string replacement
let newText = text.replace("World", "JavaScript");
console.log("Replaced:", newText);

// Safe string splitting
let parts = text.split(", ");
console.log("Parts:", parts);

// Safe string searching
console.log("Index of 'World':", text.indexOf("World"));
console.log("Starts with 'Hello':", text.startsWith("Hello"));

// Safe string padding
console.log("Padded:", text.padStart(20, "*"));

// String length is always safe
console.log("Length:", text.length);
```

```c !! c
#include <stdio.h>
#include <string.h>

int main() {
    char text[] = "Hello, World!";
    char buffer[100];
    
    // Safe string copying with bounds checking
    strncpy(buffer, text, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';  // Ensure null termination
    printf("Copied: %s\n", buffer);
    
    // Safe string concatenation
    char result[50] = "Hello";
    strncat(result, ", C Programming!", sizeof(result) - strlen(result) - 1);
    printf("Concatenated: %s\n", result);
    
    // Safe substring (manual implementation)
    char substring[20];
    int start = 0, length = 5;
    if (start >= 0 && length > 0 && start + length <= strlen(text)) {
        strncpy(substring, text + start, length);
        substring[length] = '\0';
        printf("Substring: %s\n", substring);
    }
    
    // String searching
    char* found = strstr(text, "World");
    if (found) {
        printf("Found 'World' at position: %ld\n", found - text);
    }
    
    // String comparison with length limit
    char compare[] = "Hello, World!";
    if (strncmp(text, compare, strlen(text)) == 0) {
        printf("Strings are equal\n");
    }
    
    // Safe string length checking
    if (strlen(text) < sizeof(buffer)) {
        strcpy(buffer, text);  // Safe to copy
        printf("Safely copied: %s\n", buffer);
    }
    
    return 0;
}
```
</UniversalEditor>

### 4.3 Character Arrays and String Literals

<UniversalEditor title="Character Arrays and String Literals" compare={true}>
```javascript !! js
// JavaScript - string literals and manipulation
let literal = "This is a string literal";
let template = `Template literal with ${literal}`;
let multiLine = `
    This is a
    multi-line string
`;

// String methods
console.log("Original:", literal);
console.log("Uppercase:", literal.toUpperCase());
console.log("Lowercase:", literal.toLowerCase());

// Character access
console.log("First character:", literal[0]);
console.log("Last character:", literal[literal.length - 1]);

// String modification (creates new string)
let modified = literal.replace("string", "modified");
console.log("Modified:", modified);
console.log("Original unchanged:", literal);

// String concatenation
let combined = literal + " " + "concatenated";
console.log("Combined:", combined);
```

```c !! c
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int main() {
    // String literals
    char* literal = "This is a string literal";  // Read-only
    char array[] = "This is a character array";  // Modifiable
    
    // Character array manipulation
    char text[] = "Hello, World!";
    printf("Original: %s\n", text);
    
    // Convert to uppercase
    for (int i = 0; text[i] != '\0'; i++) {
        text[i] = toupper(text[i]);
    }
    printf("Uppercase: %s\n", text);
    
    // Convert back to lowercase
    for (int i = 0; text[i] != '\0'; i++) {
        text[i] = tolower(text[i]);
    }
    printf("Lowercase: %s\n", text);
    
    // Character access
    printf("First character: %c\n", text[0]);
    printf("Last character: %c\n", text[strlen(text) - 1]);
    
    // String literal vs character array
    printf("Literal: %s\n", literal);
    // literal[0] = 'h';  // ERROR: Cannot modify string literal
    
    printf("Array: %s\n", array);
    array[0] = 't';  // OK: Can modify character array
    printf("Modified array: %s\n", array);
    
    // Multi-line string (using escape sequences)
    char multiLine[] = "This is a\nmulti-line\nstring";
    printf("Multi-line:\n%s\n", multiLine);
    
    return 0;
}
```
</UniversalEditor>

## 5. Buffer Overflow Prevention

### 5.1 Understanding Buffer Overflow

<UniversalEditor title="Buffer Overflow Prevention" compare={true}>
```javascript !! js
// JavaScript - automatic bounds checking
let str = "Hello";
let arr = [1, 2, 3, 4, 5];

// JavaScript prevents buffer overflow
console.log("String length:", str.length);
console.log("Array length:", arr.length);

// Safe access
console.log("Valid access:", str[2]);  // 'l'
console.log("Out of bounds:", str[10]);  // undefined (safe)

// Safe modification
str = str + " World";  // Creates new string
arr.push(6);  // Safe addition

// JavaScript strings are immutable
let original = "Hello";
let modified = original.toUpperCase();
console.log("Original unchanged:", original);
console.log("Modified:", modified);
```

```c !! c
#include <stdio.h>
#include <string.h>

int main() {
    char buffer[10];
    char source[] = "This string is too long for the buffer";
    
    // DANGEROUS: Buffer overflow
    // strcpy(buffer, source);  // Will overflow buffer!
    
    // SAFE: Bounded string copy
    strncpy(buffer, source, sizeof(buffer) - 1);
    buffer[sizeof(buffer) - 1] = '\0';  // Ensure null termination
    printf("Safely copied: %s\n", buffer);
    
    // Safe string concatenation
    char result[20] = "Hello";
    size_t available = sizeof(result) - strlen(result) - 1;
    strncat(result, ", World!", available);
    printf("Safely concatenated: %s\n", result);
    
    // Safe string comparison
    char str1[] = "Hello";
    char str2[] = "Hello, World!";
    
    if (strncmp(str1, str2, strlen(str1)) == 0) {
        printf("Strings match up to length of str1\n");
    }
    
    // Safe string length checking
    char input[] = "Very long input string";
    if (strlen(input) < sizeof(buffer)) {
        strcpy(buffer, input);  // Safe
        printf("Input fits in buffer: %s\n", buffer);
    } else {
        printf("Input too long for buffer\n");
    }
    
    return 0;
}
```
</UniversalEditor>

### 5.2 Safe String Functions

<UniversalEditor title="Safe String Functions" compare={true}>
```javascript !! js
// JavaScript - built-in safety
let str = "Hello, World!";

// Safe string operations
let substring = str.substring(0, 5);  // "Hello"
let replaced = str.replace("World", "JavaScript");
let split = str.split(", ");

// Safe string building
let parts = ["Hello", "World", "JavaScript"];
let joined = parts.join(", ");

// Safe string validation
if (str.length > 0 && str.length < 100) {
    console.log("String is valid length");
}

// Safe string iteration
for (let i = 0; i < str.length; i++) {
    console.log(str[i]);
}

// Modern safe iteration
for (let char of str) {
    console.log(char);
}
```

```c !! c
#include <stdio.h>
#include <string.h>

// Safe string copy function
void safe_strcpy(char* dest, const char* src, size_t dest_size) {
    strncpy(dest, src, dest_size - 1);
    dest[dest_size - 1] = '\0';
}

// Safe string concatenation function
void safe_strcat(char* dest, const char* src, size_t dest_size) {
    size_t dest_len = strlen(dest);
    size_t available = dest_size - dest_len - 1;
    
    if (available > 0) {
        strncat(dest, src, available);
    }
}

int main() {
    char buffer[20];
    char source[] = "Hello, World!";
    
    // Using safe functions
    safe_strcpy(buffer, source, sizeof(buffer));
    printf("Safely copied: %s\n", buffer);
    
    safe_strcat(buffer, " More text", sizeof(buffer));
    printf("Safely concatenated: %s\n", buffer);
    
    // Safe string validation
    char input[] = "Test string";
    if (strlen(input) > 0 && strlen(input) < sizeof(buffer)) {
        safe_strcpy(buffer, input, sizeof(buffer));
        printf("Valid input copied: %s\n", buffer);
    }
    
    // Safe string building
    char result[50] = "";
    char* parts[] = {"Hello", "World", "C", "Programming"};
    int num_parts = 4;
    
    for (int i = 0; i < num_parts; i++) {
        safe_strcat(result, parts[i], sizeof(result));
        if (i < num_parts - 1) {
            safe_strcat(result, ", ", sizeof(result));
        }
    }
    printf("Built string: %s\n", result);
    
    return 0;
}
```
</UniversalEditor>

## 6. Practical Examples

### 6.1 Array Processing Functions

<UniversalEditor title="Array Processing Functions" compare={true}>
```javascript !! js
// JavaScript - array processing
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Find maximum value
let max = Math.max(...numbers);
console.log("Maximum:", max);

// Find minimum value
let min = Math.min(...numbers);
console.log("Minimum:", min);

// Calculate average
let sum = numbers.reduce((a, b) => a + b, 0);
let average = sum / numbers.length;
console.log("Average:", average);

// Filter even numbers
let evens = numbers.filter(n => n % 2 === 0);
console.log("Even numbers:", evens);

// Map: double each number
let doubled = numbers.map(n => n * 2);
console.log("Doubled:", doubled);

// Reverse array
let reversed = [...numbers].reverse();
console.log("Reversed:", reversed);
```

```c !! c
#include <stdio.h>

// Find maximum value in array
int find_max(int arr[], int size) {
    if (size <= 0) return 0;
    
    int max = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

// Find minimum value in array
int find_min(int arr[], int size) {
    if (size <= 0) return 0;
    
    int min = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] < min) {
            min = arr[i];
        }
    }
    return min;
}

// Calculate average
double calculate_average(int arr[], int size) {
    if (size <= 0) return 0.0;
    
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += arr[i];
    }
    return (double)sum / size;
}

// Filter even numbers
int filter_evens(int arr[], int size, int result[]) {
    int count = 0;
    for (int i = 0; i < size; i++) {
        if (arr[i] % 2 == 0) {
            result[count++] = arr[i];
        }
    }
    return count;
}

// Double each element
void double_elements(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        arr[i] *= 2;
    }
}

// Reverse array
void reverse_array(int arr[], int size) {
    for (int i = 0; i < size / 2; i++) {
        int temp = arr[i];
        arr[i] = arr[size - 1 - i];
        arr[size - 1 - i] = temp;
    }
}

int main() {
    int numbers[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    printf("Original array: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
    
    // Find maximum and minimum
    printf("Maximum: %d\n", find_max(numbers, size));
    printf("Minimum: %d\n", find_min(numbers, size));
    printf("Average: %.2f\n", calculate_average(numbers, size));
    
    // Filter even numbers
    int evens[10];
    int even_count = filter_evens(numbers, size, evens);
    printf("Even numbers: ");
    for (int i = 0; i < even_count; i++) {
        printf("%d ", evens[i]);
    }
    printf("\n");
    
    // Double elements
    int doubled[10];
    for (int i = 0; i < size; i++) {
        doubled[i] = numbers[i];
    }
    double_elements(doubled, size);
    printf("Doubled: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", doubled[i]);
    }
    printf("\n");
    
    // Reverse array
    int reversed[10];
    for (int i = 0; i < size; i++) {
        reversed[i] = numbers[i];
    }
    reverse_array(reversed, size);
    printf("Reversed: ");
    for (int i = 0; i < size; i++) {
        printf("%d ", reversed[i]);
    }
    printf("\n");
    
    return 0;
}
```
</UniversalEditor>

### 6.2 String Processing Functions

<UniversalEditor title="String Processing Functions" compare={true}>
```javascript !! js
// JavaScript - string processing
let text = "  Hello, World!  ";

// Trim whitespace
let trimmed = text.trim();
console.log("Trimmed:", `"${trimmed}"`);

// Convert case
let upper = text.toUpperCase();
let lower = text.toLowerCase();
console.log("Uppercase:", upper);
console.log("Lowercase:", lower);

// Replace text
let replaced = text.replace("World", "JavaScript");
console.log("Replaced:", replaced);

// Split and join
let words = text.split(", ");
console.log("Words:", words);
let joined = words.join(" - ");
console.log("Joined:", joined);

// Check if string contains substring
let contains = text.includes("World");
console.log("Contains 'World':", contains);

// Count occurrences
let count = (text.match(/o/g) || []).length;
console.log("Count of 'o':", count);
```

```c !! c
#include <stdio.h>
#include <string.h>
#include <ctype.h>

// Trim whitespace from both ends
void trim(char* str) {
    int len = strlen(str);
    int start = 0, end = len - 1;
    
    // Find start of non-whitespace
    while (start < len && isspace(str[start])) {
        start++;
    }
    
    // Find end of non-whitespace
    while (end >= start && isspace(str[end])) {
        end--;
    }
    
    // Shift string to beginning
    if (start > 0) {
        for (int i = 0; i <= end - start; i++) {
            str[i] = str[start + i];
        }
        str[end - start + 1] = '\0';
    } else if (end < len - 1) {
        str[end + 1] = '\0';
    }
}

// Convert to uppercase
void to_upper(char* str) {
    for (int i = 0; str[i] != '\0'; i++) {
        str[i] = toupper(str[i]);
    }
}

// Convert to lowercase
void to_lower(char* str) {
    for (int i = 0; str[i] != '\0'; i++) {
        str[i] = tolower(str[i]);
    }
}

// Replace substring
int replace_substring(char* str, const char* old, const char* new) {
    char* found = strstr(str, old);
    if (!found) return 0;
    
    int old_len = strlen(old);
    int new_len = strlen(new);
    int str_len = strlen(str);
    
    if (new_len > old_len) {
        // Need to shift characters
        int diff = new_len - old_len;
        for (int i = str_len; i >= found - str + old_len; i--) {
            str[i + diff] = str[i];
        }
    }
    
    strncpy(found, new, new_len);
    return 1;
}

// Count occurrences of character
int count_char(const char* str, char ch) {
    int count = 0;
    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] == ch) {
            count++;
        }
    }
    return count;
}

// Split string by delimiter
int split_string(const char* str, char delimiter, char* parts[], int max_parts) {
    int count = 0;
    int len = strlen(str);
    char* temp = malloc(len + 1);
    strcpy(temp, str);
    
    char* token = strtok(temp, &delimiter);
    while (token && count < max_parts) {
        parts[count++] = strdup(token);
        token = strtok(NULL, &delimiter);
    }
    
    free(temp);
    return count;
}

int main() {
    char text[] = "  Hello, World!  ";
    printf("Original: \"%s\"\n", text);
    
    // Trim whitespace
    trim(text);
    printf("Trimmed: \"%s\"\n", text);
    
    // Convert case
    char upper[50];
    strcpy(upper, text);
    to_upper(upper);
    printf("Uppercase: %s\n", upper);
    
    char lower[50];
    strcpy(lower, text);
    to_lower(lower);
    printf("Lowercase: %s\n", lower);
    
    // Replace substring
    char replaced[50];
    strcpy(replaced, text);
    if (replace_substring(replaced, "World", "C Programming")) {
        printf("Replaced: %s\n", replaced);
    }
    
    // Count occurrences
    printf("Count of 'o': %d\n", count_char(text, 'o'));
    
    // Split string
    char* parts[10];
    int part_count = split_string(text, ',', parts, 10);
    printf("Split parts: ");
    for (int i = 0; i < part_count; i++) {
        printf("\"%s\" ", parts[i]);
        free(parts[i]);
    }
    printf("\n");
    
    return 0;
}
```
</UniversalEditor>

## 7. Exercises

### Exercise 1: Array Operations
Create a C program that:
1. Declares an array of 10 integers
2. Fills it with random numbers
3. Finds the maximum, minimum, and average
4. Sorts the array in ascending order
5. Searches for a specific value

### Exercise 2: String Manipulation
Write a C program that:
1. Takes a string input from the user
2. Removes all vowels from the string
3. Converts the result to uppercase
4. Reverses the string
5. Counts the number of consonants

### Exercise 3: 2D Array Processing
Create a C program that:
1. Creates a 3x3 matrix
2. Fills it with numbers
3. Calculates the sum of each row and column
4. Finds the maximum value in the matrix
5. Transposes the matrix

## 8. Summary

### Key Concepts Covered
- **Array Declaration**: Fixed-size, contiguous memory blocks
- **Array-Pointer Relationship**: Arrays decay to pointers
- **Multidimensional Arrays**: 2D and 3D array handling
- **String Handling**: Character arrays with null termination
- **Buffer Safety**: Preventing buffer overflow attacks
- **String Functions**: Safe string manipulation

### JavaScript vs C Differences
- **Dynamic vs Fixed Size**: JavaScript arrays grow/shrink, C arrays are fixed
- **Bounds Checking**: JavaScript has automatic bounds checking, C requires manual checking
- **String Handling**: JavaScript strings are objects, C strings are character arrays
- **Memory Management**: JavaScript is automatic, C requires explicit management

### Best Practices
1. **Always check array bounds** before accessing elements
2. **Use safe string functions** to prevent buffer overflow
3. **Initialize arrays** properly to avoid undefined behavior
4. **Validate input** before processing strings
5. **Use sizeof()** to calculate array sizes safely
6. **Handle null termination** properly in strings

### Next Steps
In the next module, we'll explore **Functions and Stack Management**, where you'll learn how functions work in C, parameter passing mechanisms, and how the call stack operates - concepts that are hidden from JavaScript developers but crucial for understanding C's memory model. 